###############################################################################
##########  PACKAGE:  api_calls.pm
##########  PURPOSE:  Functions to perform the calls to the eve api
###############################################################################
package api_calls;

use strict;
use warnings;
use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
use XML::Simple;
use Data::Dumper qw(Dumper);

use eve_const;
use api_utils;
use api_loader;

use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(
	get_account_characters
	get_account_accountstatus
	get_accountbalance
	get_walletjournal
	get_char_charactersheet
	get_eve_reftypes
	get_eve_errorlist
	get_eve_certificatetree
	get_eve_skilltree
	get_server_serverstatus
);

###############################################################################
##### GET ACCOUNT CHARACTERS LIST
##### INPUTS:  userid, apiroot, apikey
##### OUTPUTS:  %apidata{account}{characters}
###############################################################################
sub get_account_characters { 
	logger("--  BEGIN get_account_characters");
	my $profiles = $_[0];
	my $filename = "account_Characters_$profiles->{ACTIVE_PROFILE}";
   my $text     = read_cache_file($filename);
	my $test     = 0;
	my $xml      = '';
	my $apiroot  = name2root($profiles->{$profiles->{ACTIVE_PROFILE}}{root});
	my $userid   = $profiles->{$profiles->{ACTIVE_PROFILE}}{id};
	my $apikey   = $profiles->{$profiles->{ACTIVE_PROFILE}}{key};
	my $apidata;
	
	if ($text) {
		$xml = XMLin($text);
		data_dump($filename, $xml);
   	if (cache_expired($xml->{cachedUntil})) {
			logger("--  --  CACHE EXPIRED");
			$test = 1;
		} else {
			$test = 0;
		}
	} else {
		$test = 1;
	}
	if ($test) {
		print "FETCHING NEW DATA\n";
      my $ua  = LWP::UserAgent->new;
      my $req = POST $apiroot.API_ACCOUNT_CHARACTERS, [ userID => $userid, apiKey => $apikey ];
      my $res = $ua->request($req);
      unless ($res->is_success) {
			fail("api_calls", "get_account_characters", "Error: " . $res->status_line);
      }
      $text = $res->decoded_content;
		if ($text =~ /\<error code=\"(\d+)\"\>(.+)\<\/error\>/g) {
			fail("api_calls", "get_account_characters", "API ERROR CODE: $1  $2");
		}
      write_cache_file($filename, $text);
		$xml = XMLin($text);
		data_dump($filename, $xml);
   } else {
		print "USING CACHED DATA\n";
	}
	$apidata = load_account_characters($xml);
	logger("--  END get_account_characters");
   return $apidata; 
}
 
###############################################################################
##### GET ACCOUNT ACCOUNTSTATUS LIST
##### INPUTS:  userid
##### OUTPUTS:  %apidata{account}{accountstatus}
###############################################################################
sub get_account_accountstatus {
	logger("--  BEGIN get_account_accountstatus");
	my $profiles = $_[0];
	my $apiroot  = name2root($profiles->{$profiles->{ACTIVE_PROFILE}}{root});
	my $userid   = $profiles->{$profiles->{ACTIVE_PROFILE}}{id};
	my $apikey   = $profiles->{$profiles->{ACTIVE_PROFILE}}{key};
	my $filename = "account_AccountStatus_$userid";
   my $text     = read_cache_file($filename);
	my $test     = 0;
	my $xml      = '';
	my $apidata;

	if ($text) {
		$xml = XMLin($text);
		data_dump($filename, $xml);
   	if (cache_expired($xml->{cachedUntil})) {
			logger("--  --  CACHE EXPIRED");
			$test = 1;
		} else {
			$test = 0;
		}
	} else {
		$test = 1;
	}
	if ($test) {
	   my $ua  = LWP::UserAgent->new;
   	my $req = POST $apiroot.API_ACCOUNT_ACCOUNTSTATUS, [ userID => $userid, apiKey => $apikey ];
   	my $res = $ua->request($req);
   	unless ($res->is_success) {
      	fail("api_calls", "get_account_accountstatus", "Error: " . $res->status_line);
   	}
   	$text = $res->decoded_content;
		if ($text =~ /\<error code=\"(\d+)\"\>(.+)\<\/error\>/g) {
			fail("api_calls", "get_account_accountstatus", "API ERROR CODE: $1  $2");
		}
		write_cache_file($filename, $text);
		$xml = XMLin($text);
		data_dump($filename, $xml);
	} else {
		print "USING CACHED DATA\n";
	}
	$apidata = load_account_accountstatus($xml);
   print "Account is paid until ".$apidata->{paiduntil}."\n";
	logger("--  END get_account_accountstatus");
	return $apidata;
}

###############################################################################
##### GET CHAR CHARACTERSHEET LIST
##### INPUTS:  userid, charid
##### OUTPUTS:  %apidata->{char}{charactersheet}
###############################################################################
sub get_char_charactersheet {
	logger("--  BEGIN get_char_charactersheet");
	my $profiles = $_[0];
	my $apiroot  = name2root($profiles->{$profiles->{ACTIVE_PROFILE}}{root});
	my $userid   = $profiles->{$profiles->{ACTIVE_PROFILE}}{id};
	my $apikey   = $profiles->{$profiles->{ACTIVE_PROFILE}}{key};
	my $charid   = $_[1];
	my $filename = "char_CharacterSheet_$userid-$charid";
	my $text     = read_cache_file($filename);
	my $test     = 0;
	my $xml      = '';
	my $apidata;

	if ($text) {
		$xml = XMLin($text, ForceArray => [ 'row' ]);
		data_dump($filename, $xml);
		if (cache_expired($xml->{cachedUntil})) {
			logger("--  --  CACHE EXPIRED");
			$test = 1;
		} else {
			$test = 0;
		}
	} else {
		$test = 1;
	}
	if ($test) {
		my $ua  = LWP::UserAgent->new;
		my $req = POST $apiroot.API_CHAR_CHARACTERSHEET, [ userID => $userid, apikey => $apikey, characterID => $charid ];
		my $res = $ua->request($req);
		unless ($res->is_success) {
			fail("api_calls", "get_char_charactersheet", "Error: ".$res->status_line);
		}
		$text = $res->decoded_content;
		if ($text =~ /\<error code=\"(\d+)\"\>(.+)\<\/error\>/g) {
			fail("api_calls", "get_char_charactersheet", "API ERROR CODE: $1  $2");
		}
		write_cache_file($filename, $text);
		$xml = XMLin($text, ForceArray => [ 'row' ]);
		data_dump($filename, $xml);
	} else {
		print "USING CACHED DATA\n";
	}
	$apidata = load_char_charactersheet($xml);
	logger("--  END get_char_charactersheet");
	return $apidata;
}

###############################################################################
##### GET ACCOUNT BALANCE LIST
##### INPUTS:  userid, category (must be 'char' or 'corp'), charid
##### OUTPUTS:  %apidata->{$category}{accountbalance}
###############################################################################
sub get_accountbalance {
	logger("--  BEGIN get_accountbalance");
	my $profiles = $_[0];
	my $apiroot  = name2root($profiles->{$profiles->{ACTIVE_PROFILE}}{root});
	my $userid   = $profiles->{$profiles->{ACTIVE_PROFILE}}{id};
	my $apikey   = $profiles->{$profiles->{ACTIVE_PROFILE}}{key};
	my $category = $_[1];
	my $charid   = $_[2];
	my $filename = $category . "_AccountBalance_$userid-$charid";
	my $text     = read_cache_file($filename);
	my $test     = 0;
	my $xml      = '';
	my $apidata;
	
	if ($text) {
		$xml = XMLin($text, ForceArray => [ 'row' ]);
		data_dump($filename, $xml);
		if (cache_expired($xml->{cachedUntil})) {
			logger("--  --  CACHE EXPIRED");
			$test = 1;
		} else {
			$test = 0;
		}
	} else {
		$test = 1;
	}
	if ($test) {
		my $ua;
		my $req;
		my $res;
		if ($category eq 'corp') {
	   	$ua  = LWP::UserAgent->new;
	   	$req = POST $apiroot.API_CORP_ACCOUNTBALANCE, [ userID => $userid, apiKey => $apikey, characterID => $charid ];
	   	$res = $ua->request($req);
		} elsif ($category eq 'char') {
			$ua  = LWP::UserAgent->new;
			$req = POST $apiroot.API_CHAR_ACCOUNTBALANCE, [ userID => $userid, apiKey => $apikey, characterID => $charid ];
			$res = $ua->request($req);
		} else {
			print "\n\nINVALID CATEGORY VALUE:  $category\n\n";
			return 0;
		}
   	unless ($res->is_success) {
      	fail("api_calls", "get_accountbalance", "Error: ".$res->status_line);
   	}
   	$text = $res->decoded_content;
		if ($text =~ /\<error code=\"(\d+)\"\>(.+)\<\/error\>/g) {
			fail("api_calls", "get_accountbalance", "API ERROR CODE: $1  $2");
		}
		write_cache_file($filename, $text);
		$xml = XMLin($text, ForceArray => [ 'row' ]);
		data_dump($filename, $xml);
	} else {
		print "USING CACHED DATA\n";
	}
	$apidata = load_accountbalances($xml);
   print "Account Balances:\n";
	foreach my $i (keys(%{$apidata->{accountid}})) {
		print ' ['.$apidata->{accountid}{$i}{accountkey}.'] '.$apidata->{accountid}{$i}{balance}."\n";
	}
	logger("--  END get_accountbalance");
	return $apidata;
}

###############################################################################
##### GET WALLET JOURNAL LIST
##### INPUTS:  userid, category (must be 'char' or 'corp'), charid
##### OUTPUTS:  %apidata->{$category}{walletjournal}
###############################################################################
##### WALLET JOURNAL DATA	
sub get_walletjournal {
	logger("--  BEGIN get_walletjournal");
	my $profiles = $_[0];
	my $apiroot  = name2root($profiles->{$profiles->{ACTIVE_PROFILE}}{root});
	my $userid   = $profiles->{$profiles->{ACTIVE_PROFILE}}{id};
	my $apikey   = $profiles->{$profiles->{ACTIVE_PROFILE}}{key};
	my $category = $_[1];
	my $charid   = $_[2];
	my $data     = $_[3];
	my $fname    = $category . "_WalletJournal_$userid-$charid-";
	my $test     = 0;
	my $rowcount = 50;
	my $rows     = 0;
	my $fromid   = 0;
	my $walk     = 1;
	my $accountkey;
	my $text;
	my $xml;
	my $apidata;

	foreach my $accountid (keys(%{$data->{accountid}})) {
		$accountkey = $data->{accountid}{$accountid}{accountkey};
		my $filename  = $fname . $accountkey;
		print "READING ACCOUNT $accountkey\n";
		$text      = read_cache_file($filename);
		$test      = 0;
		$rows      = 0;
		$fromid    = 0;
		$walk      = 1;
		if ($text) {
			$xml = XMLin($text, ForceArray => [ 'row' ]);
			data_dump($filename, $xml);
			if (cache_expired($xml->{cachedUntil})) {
				logger("--  --  CACHE EXPIRED");
				$test = 1;
			} else {
				$test = 0;
				$apidata = load_walletjournal($accountkey, $xml);
			}
		} else {
			$test = 1;
		}
		if ($test) {
			my $api;
			my $walks = 1;
			while ($walk) {
				my $ua;
				my $req;
				my $res;
				if ($category eq 'corp') {
					$ua = LWP::UserAgent->new;
					if ($fromid == 0) {
						$req = POST $apiroot.API_CORP_WALLETJOURNAL, [ userID => $userid, apikey => $apikey, characterID => $charid, accountKey => $accountkey, rowCount => $rowcount ];
					} else {
						$req = POST $apiroot.API_CORP_WALLETJOURNAL, [ userID => $userid, apikey => $apikey, characterID => $charid, accountKey => $accountkey, fromID => $fromid, rowCount => $rowcount ];
					}
					$res = $ua->request($req);
				} elsif ($category eq 'char') {
					$ua = LWP::UserAgent->new;
					if ($fromid == 0) {
						$req = POST $apiroot.API_CHAR_WALLETJOURNAL, [ userID => $userid, apikey => $apikey, characterID => $charid, accountKey => $accountkey, rowCount => $rowcount ];
					} else {
						$req = POST $apiroot.API_CHAR_WALLETJOURNAL, [ userID => $userid, apikey => $apikey, characterID => $charid, accountKey => $accountkey, fromID => $fromid, rowCount => $rowcount ];
					}
					$res = $ua->request($req);
				} else {
					print "\n\nINVALID CATEGORY VALUE:  $category\n\n";
					return 0;
				}
				unless ($res->is_success) {
					fail("api_calls", "get_walletjournal", "Error: ".$res->status_line);
				}
				$text = $res->decoded_content;
				if ($text =~ /\<error code=\"(\d+)\"\>(.+)\<\/error\>/g) {
					fail("api_calls", "get_walletjournal", "API ERROR CODE: $1  $2");
				}
				write_cache_file($filename, $text);
				$xml = XMLin($text, ForceArray => [ 'row' ]);
				data_dump($filename, $xml);
				$api->{$walks} = load_walletjournal($accountkey, $xml);
				data_dump("API_$walks", $api);
				$walks++;
				my @dates;
				my $i = 0;
				for ($i=0; $i<=$#{$xml->{result}{rowset}{row}}; $i++) {
					push @dates, $xml->{result}{rowset}{row}[$i]{refID};
				}
				@dates = sort(@dates);
				if ($i==$rowcount) {
					$fromid = $dates[0];
					$walk = 1;
				} else {
					$walk = 0;
				}
			}
			foreach my $i (sort(keys(%{$api}))) {
				$apidata->{cacheduntil} = $api->{$i}{cacheduntil};
				$apidata->{currenttime} = $api->{$i}{currenttime};
				$apidata->{version}     = $api->{$i}{version};
				foreach my $j (sort(keys(%{$api->{$i}{accountkey}{$accountkey}{entries}}))) {
					$apidata->{accountkey}{$accountkey}{entries}{$j} = $api->{$i}{accountkey}{$accountkey}{entries}{$j};
				}
			}
		} else {
			print "USING CACHED DATA\n";
		}
	}
	logger("--  END get_walletjournal");
	return $apidata;
}

###############################################################################
##### GET EVE REFTYPES LIST
##### INPUTS:  None
##### OUTPUTS:  %apidata->{eve}{reftypes}
###############################################################################
sub get_eve_reftypes {
	logger("--  BEGIN get_eve_reftypes");
	my $profiles = $_[0];
	my $apiroot  = name2root($profiles->{$profiles->{ACTIVE_PROFILE}}{root});
	my $filename = "eve_RefTypes";
	my $text     = read_cache_file($filename);
	my $test     = 0;
	my $xml      = '';
	my $apidata;
	
	if ($text) {
		$xml = XMLin($text, ForceArray => [ 'row' ]);
		data_dump($filename, $xml);
		if (cache_expired($xml->{cachedUntil})) {
			logger("--  --  CACHE EXPIRED");
			$test = 1;
		} else {
			$test = 0;
		}
	} else {
		$test = 1;
	}
	if ($test) {
   	my $ua  = LWP::UserAgent->new;
   	my $req = POST $apiroot.API_EVE_REFTYPES;
   	my $res = $ua->request($req);
   	unless ($res->is_success) {
      	fail("api_calls", "get_eve_reftypes", "Error: ".$res->status_line);
   	}
   	$text = $res->decoded_content;
		if ($text =~ /\<error code=\"(\d+)\"\>(.+)\<\/error\>/g) {
			fail("api_calls", "get_eve_reftypes", "API ERROR CODE: $1  $2");
		}
		write_cache_file($filename, $text);
		$xml = XMLin($text, ForceArray => [ 'row' ]);
		data_dump($filename, $xml);
	} else {
		print "USING CACHED DATA\n";
	}
	$apidata = load_eve_reftypes($xml);
	logger("--  END get_eve_reftypes");
	return $apidata;
}

###############################################################################
##### GET EVE ERROR LIST
##### INPUTS:  None
##### OUTPUTS:  %apidata->{eve}{errorlist}
###############################################################################
sub get_eve_errorlist {
	logger("--  BEGIN get_eve_errorlist");
	my $profiles = $_[0];
	my $apiroot  = name2root($profiles->{$profiles->{ACTIVE_PROFILE}}{root});
	my $filename = "eve_ErrorList";
	my $text     = read_cache_file($filename);
	my $test     = 0;
	my $xml      = '';
	my $apidata;
	
	if ($text) {
		$xml = XMLin($text, ForceArray => [ 'row' ]);
		data_dump($filename, $xml);
		if (cache_expired($xml->{cachedUntil})) {
			logger("--  --  CACHE EXPIRED");
			$test = 1;
		} else {
			$test = 0;
		}
	} else {
		$test = 1;
	}
	if ($test) {
   	my $ua  = LWP::UserAgent->new;
   	my $req = POST $apiroot.API_EVE_ERRORLIST;
   	my $res = $ua->request($req);
   	unless ($res->is_success) {
      	fail("api_calls", "get_eve_errorlist", "Error: ".$res->status_line);
   	}
   	$text = $res->decoded_content;
		if ($text =~ /\<error code=\"(\d+)\"\>(.+)\<\/error\>/g) {
			fail("api_calls", "get_eve_errorlist", "API ERROR CODE: $1  $2");
		}
		write_cache_file($filename, $text);
		$xml = XMLin($text, ForceArray => [ 'row' ]);
		data_dump($filename, $xml);
	} else {
		print "USING CACHED DATA\n";
	}
	$apidata = load_eve_errorlist($xml);
	logger("--  END get_eve_errorlist");
	return $apidata;
}

###############################################################################
##### GET EVE CERTIFICATE TREE
##### INPUTS:  None
##### OUTPUTS:  %apidata->{eve}{certificatetree}
###############################################################################
sub get_eve_certificatetree {
	logger("--  BEGIN get_eve_certificatetree");
	my $profiles = $_[0];
	my $apiroot  = name2root($profiles->{$profiles->{ACTIVE_PROFILE}}{root});
	my $filename = "eve_CertificateTree";
	my $text     = read_cache_file($filename);
	my $test     = 0;
	my $xml      = '';
	my $apidata;
	
	if ($text) {
		$xml = XMLin($text, ForceArray => [ 'row' ]);
		data_dump($filename, $xml);
		if (cache_expired($xml->{cachedUntil})) {
			logger("--  --  CACHE EXPIRED");
			$test = 1;
		} else {
			$test = 0;
		}
	} else {
		$test = 1;
	}
	if ($test) {
   	my $ua  = LWP::UserAgent->new;
   	my $req = POST $apiroot.API_EVE_CERTIFICATETREE;
   	my $res = $ua->request($req);
   	unless ($res->is_success) {
      	fail("api_calls", "get_eve_certificatetree", "Error: ".$res->status_line);
   	}
   	$text = $res->decoded_content;
		if ($text =~ /\<error code=\"(\d+)\"\>(.+)\<\/error\>/g) {
			fail("api_calls", "get_eve_certificatetree", "API ERROR CODE: $1  $2");
		}
		write_cache_file($filename, $text);
		$xml = XMLin($text, ForceArray => [ 'row' ]);
		data_dump($filename, $xml);
	} else {
		print "USING CACHED DATA\n";
	}
	$apidata = load_eve_certificatetree($xml);
	logger("--  END get_eve_certificatetree");
	return $apidata;
}

###############################################################################
##### GET EVE SKILL TREE
##### INPUTS:  None
##### OUTPUTS:  %apidata->{eve}{skilltree}
###############################################################################
sub get_eve_skilltree {
	logger("--  BEGIN get_eve_skilltree");
	my $profiles = $_[0];
	my $apiroot  = name2root($profiles->{$profiles->{ACTIVE_PROFILE}}{root});
	my $filename = "eve_SkillTree";
	my $text     = read_cache_file($filename);
	my $test     = 0;
	my $xml      = '';
	my $apidata;
	
	if ($text) {
		$xml = XMLin($text, ForceArray => [ 'row' ]);
		data_dump($filename, $xml);
		if (cache_expired($xml->{cachedUntil})) {
			logger("--  --  CACHE EXPIRED");
			$test = 1;
		} else {
			$test = 0;
		}
	} else {
		$test = 1;
	}
	if ($test) {
   	my $ua  = LWP::UserAgent->new;
   	my $req = POST $apiroot.API_EVE_SKILLTREE;
   	my $res = $ua->request($req);
   	unless ($res->is_success) {
      	fail("api_calls", "get_eve_skilltree", "Error: ".$res->status_line);
   	}
   	$text = $res->decoded_content;
		if ($text =~ /\<error code=\"(\d+)\"\>(.+)\<\/error\>/g) {
			fail("api_calls", "get_eve_skilltree", "API ERROR CODE: $1  $2");
		}
		write_cache_file($filename, $text);
		$xml = XMLin($text, ForceArray => [ 'row' ]);
		data_dump($filename, $xml);
	} else {
		print "USING CACHED DATA\n";
	}
	$apidata = load_eve_skilltree($xml);
	logger("--  END get_eve_skilltree");
	return $apidata;
}

###############################################################################
##### GET SERVER SERVERSTATUS
##### INPUTS:  None
##### OUTPUTS:  %apidata->{server}{serverstatus}
###############################################################################
sub get_server_serverstatus {
	logger("--  BEGIN get_server_serverstatus");
	my $profiles = $_[0];
	my $apiroot  = name2root($profiles->{$profiles->{ACTIVE_PROFILE}}{root});
	my $filename = "server_ServerStatus";
	my $text     = read_cache_file($filename);
	my $test     = 0;
	my $xml      = '';
	my $apidata;
	
	if ($text) {
		$xml = XMLin($text, ForceArray => [ 'row' ]);
		data_dump($filename, $xml);
		if (cache_expired($xml->{cachedUntil})) {
			logger("--  --  CACHE EXPIRED");
			$test = 1;
		} else {
			$test = 0;
		}
	} else {
		$test = 1;
	}
	if ($test) {
   	my $ua  = LWP::UserAgent->new;
   	my $req = POST $apiroot.API_SERVER_SERVERSTATUS;
   	my $res = $ua->request($req);
   	unless ($res->is_success) {
      	fail("api_calls", "get_server_serverstatus", "Error: ".$res->status_line);
   	}
   	$text = $res->decoded_content;
		if ($text =~ /\<error code=\"(\d+)\"\>(.+)\<\/error\>/g) {
			fail("api_calls", "get_server_serverstatus", "API ERROR CODE: $1  $2");
		}
		write_cache_file($filename, $text);
		$xml = XMLin($text, ForceArray => [ 'row' ]);
		data_dump($filename, $xml);
	} else {
		print "USING CACHED DATA\n";
	}
	$apidata = load_server_serverstatus($xml);
	logger("--  END get_server_serverstatus");
	return $apidata;
}


1;
